<?php
namespace WDB\Wrapper;
use WDB;

/**
 * Table record wrapping class. Contains exactly one selected row of a table.
 *
 * @author Richard Ejem <richard(at)ejem.cz>
 * @package WDB
 */
interface iRecord extends \ArrayAccess, \Countable, \Iterator
{
    /** when updating, write only columns that were changed (value is not equal to the original) */
    const WM_CHANGED = 1;
    /**  when updating, write only columns that were written (value may be equal to the original) */
    const WM_WRITTEN = 2;
    /** when updating, force write all columns */
    const WM_ALL = 3;

    /**
     * get table owning this record
     *
     * @return iTable
     */
    public function getTable();

    /**
     * Get the Field object for the specified column.
     *
     * @param string column name
     * @return Field
     */
    public function getField($name);

    // <editor-fold defaultstate="collapsed" desc="validation">
    /**
     * Returns all validators bound to this record
     *
     * @return WDB\Validation\iValidator[]
     */
    public function getValidators();

    /**
     * get validation error messages
     *
     * @return string[]
     */
    public function getValidationErrors();

    /**
     * Add validation errors to validation errors container
     *
     * @param string[]
     */
    public function addValidationErrors($errors);

    /**
     * binds a validator object
     *
     * @param WDB\Validation\iValidator
     */
    public function addValidator(WDB\Validation\iValidator $validator);

    /**
     * Removes bound validator
     *
     * @param WDB\Validation\iValidator
     */
    public function removeValidator(WDB\Validation\iValidator $validator);

    /**
     * Returns whether to validate this record or not upon save
     *
     * @return bool
     */
    public function isValidatedUponSave();
    /**
     * Configures whether to validate this record or not upon save
     *
     * @param bool
     */
    public function setValidateUponSave($value);

    /**
     * validates current record
     * @throws WDB\Exception\ValidationFailed
     */
    public function validate();
    // </editor-fold>

    //<editor-fold defaultstate="collapsed" desc="persistence">

    /**
     * Saves this record to database.
     *
     * @return bool
     */
    public function save();

    /**
     * Removes row corresponding to this record from the database.
     *
     * @return bool
     */
    public function delete();

    /**
     * Returns true when a value of any column was changed since last load/save
     * (always true for all columns of new row).
     *
     * @return bool
     */
    public function changed();

    /**
     * Returns true when a value of any column was written since last load/save.
     * In compare with changed() method, this returns true even when newly assigned value
     * is equal to original value.
     *
     * @return bool
     */
    public function written();

    /**
     * Set column write mode when updating
     *
     * @param int enumeration of iRecord::WM_*
     */
    public function setWriteMode($mode);

    /**
     * Get column write mode when updating
     *
     * @return int enumeration of iRecord::WM_*
     */
    public function getWriteMode();

    /**
     * Returns true if this is a new record, not persisted yet in database.
     *
     * @return bool
     */
    public function isNew();
    // </editor-fold>

    //<editor-fold defaultstate="collapsed" desc="identification">
    /**
     * Returns key=>values of columns which are uniquely identifying the record. It should be a table primary key or a reasonable substitution.
     *
     * @return array
     */
    public function getIdentificationKey();

    /**
     * returns a string identifier of a row built from primary key (should be as
     * simple as possible)
     * @return string
     */
    public function getStringKey();
    // </editor-fold>

    //<editor-fold defaultstate="collapsed" desc="webui config">
    /**
     * Determines whether this record has an accessible detail view.
     * A record must have valid primary key to be accessible in detail view.
     *
     * @return bool
     */
    public function isUIDetail();

    /**
     * Determines whether this record has an accessible edit view.
     * A record must have valid primary key to be accessible in edit view.
     *
     * @return bool
     */
    public function isUIEdit();

    /**
     * Determines whether this record can be deleted from UI.
     * A record must have valid primary key to be deleted in UI.
     *
     * @return bool
     */
    public function isUIDelete();
    //</editor-fold>
}